package service

import (
	"context"
	"crypto/md5"
	"encoding/hex"
	pb "doctor-srv/basic/proto"
	"doctor-srv/basic/config"
	"doctor-srv/handler/model"
	"fmt"
	"math/rand"
	"time"
)

type DoctorService struct {
	pb.UnimplementedDoctorServer
}

// GenerateSalt 生成盐值
func GenerateSalt() string {
	rand.Seed(time.Now().UnixNano())
	const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
	b := make([]byte, 32)
	for i := range b {
		b[i] = charset[rand.Intn(len(charset))]
	}
	return string(b)
}

// Md5 MD5加密
func Md5(str string) string {
	h := md5.New()
	h.Write([]byte(str))
	return hex.EncodeToString(h.Sum(nil))
}

// RegisterDoctor 医生注册
func (s *DoctorService) RegisterDoctor(ctx context.Context, req *pb.RegisterDoctorReq) (*pb.RegisterDoctorResp, error) {
	// 检查手机号是否已存在
	var existDoctor model.Doctor
	err := existDoctor.GetDoctorByPhone(config.DB, req.Phone)
	if err == nil {
		return &pb.RegisterDoctorResp{
			DoctorId: 0,
			Message:  "手机号已存在",
		}, nil
	}

	// TODO: 验证短信验证码
	// if req.SmsCode != "正确的验证码" {
	//     return &pb.RegisterDoctorResp{Message: "验证码错误"}, nil
	// }

	// 创建医生
	salt := GenerateSalt()
	doctor := model.Doctor{
		Name:     req.Name,
		Phone:    req.Phone,
		Password: Md5(req.Password + salt),
		Salt:     salt,
	}

	if err := doctor.RegisterDoctor(config.DB); err != nil {
		return &pb.RegisterDoctorResp{
			DoctorId: 0,
			Message:  "注册失败",
		}, err
	}

	return &pb.RegisterDoctorResp{
		DoctorId: int64(doctor.ID),
		Message:  "注册成功",
	}, nil
}

// LoginDoctor 医生登录
func (s *DoctorService) LoginDoctor(ctx context.Context, req *pb.LoginDoctorReq) (*pb.LoginDoctorResp, error) {
	// TODO: 验证图形验证码
	// if req.Captcha != "正确的验证码" {
	//     return &pb.LoginDoctorResp{Message: "验证码错误"}, nil
	// }

	// 查询医生
	var doctor model.Doctor
	err := doctor.GetDoctorByPhone(config.DB, req.Phone)
	if err != nil {
		return &pb.LoginDoctorResp{
			DoctorId: 0,
			Token:    "",
		}, fmt.Errorf("手机号不存在")
	}

	// 验证密码
	if Md5(req.Password+doctor.Salt) != doctor.Password {
		return &pb.LoginDoctorResp{
			DoctorId: 0,
			Token:    "",
		}, fmt.Errorf("密码错误")
	}

	// TODO: 生成JWT Token
	token := fmt.Sprintf("token_%d_%d", doctor.ID, time.Now().Unix())

	return &pb.LoginDoctorResp{
		DoctorId: int64(doctor.ID),
		Token:    token,
		DoctorInfo: &pb.DoctorInfo{
			DoctorId:    int64(doctor.ID),
			Name:        doctor.Name,
			Phone:       doctor.Phone,
			Specialty:   doctor.Specialty,
			Department:  doctor.Department,
			Title:       doctor.Title,
			Hospital:    doctor.Hospital,
			AvatarUrl:   doctor.AvatarUrl,
			AuditStatus: int32(doctor.AuditStatus),
		},
	}, nil
}

// UploadQualification 上传医生资质
func (s *DoctorService) UploadQualification(ctx context.Context, req *pb.UploadQualificationReq) (*pb.UploadQualificationResp, error) {
	var doctor model.Doctor
	err := doctor.GetDoctorByID(config.DB, req.DoctorId)
	if err != nil {
		return &pb.UploadQualificationResp{
			Success: false,
			Message: "医生不存在",
		}, err
	}

	doctor.QualificationCertUrl = req.QualificationCertUrl
	doctor.PracticeCertUrl = req.PracticeCertUrl
	doctor.AuditStatus = 0 // 设置为待审核

	if err := doctor.UpdateDoctor(config.DB); err != nil {
		return &pb.UploadQualificationResp{
			Success: false,
			Message: "上传失败",
		}, err
	}

	return &pb.UploadQualificationResp{
		Success: true,
		Message: "上传成功，等待审核",
	}, nil
}

// UpdateDoctorInfo 完善医生信息
func (s *DoctorService) UpdateDoctorInfo(ctx context.Context, req *pb.UpdateDoctorInfoReq) (*pb.UpdateDoctorInfoResp, error) {
	var doctor model.Doctor
	err := doctor.GetDoctorByID(config.DB, req.DoctorId)
	if err != nil {
		return &pb.UpdateDoctorInfoResp{
			Success: false,
			Message: "医生不存在",
		}, err
	}

	doctor.Specialty = req.Specialty
	doctor.Department = req.Department
	doctor.ConsultationScope = req.ConsultationScope
	doctor.Introduction = req.Introduction
	doctor.Title = req.Title
	doctor.Hospital = req.Hospital

	if err := doctor.UpdateDoctor(config.DB); err != nil {
		return &pb.UpdateDoctorInfoResp{
			Success: false,
			Message: "更新失败",
		}, err
	}

	return &pb.UpdateDoctorInfoResp{
		Success: true,
		Message: "更新成功",
	}, nil
}

// GetDoctorAuditStatus 获取医生审核状态
func (s *DoctorService) GetDoctorAuditStatus(ctx context.Context, req *pb.GetDoctorAuditStatusReq) (*pb.GetDoctorAuditStatusResp, error) {
	var doctor model.Doctor
	err := doctor.GetDoctorByID(config.DB, req.DoctorId)
	if err != nil {
		return nil, err
	}

	return &pb.GetDoctorAuditStatusResp{
		AuditStatus: int32(doctor.AuditStatus),
		AuditReason: doctor.AuditReason,
	}, nil
}

// GetDoctorInfo 获取医生信息
func (s *DoctorService) GetDoctorInfo(ctx context.Context, req *pb.GetDoctorInfoReq) (*pb.GetDoctorInfoResp, error) {
	var doctor model.Doctor
	err := doctor.GetDoctorByID(config.DB, req.DoctorId)
	if err != nil {
		return nil, err
	}

	return &pb.GetDoctorInfoResp{
		DoctorInfo: &pb.DoctorInfo{
			DoctorId:    int64(doctor.ID),
			Name:        doctor.Name,
			Phone:       doctor.Phone,
			Specialty:   doctor.Specialty,
			Department:  doctor.Department,
			Title:       doctor.Title,
			Hospital:    doctor.Hospital,
			AvatarUrl:   doctor.AvatarUrl,
			AuditStatus: int32(doctor.AuditStatus),
		},
	}, nil
}

// GetDoctorList 获取医生列表
func (s *DoctorService) GetDoctorList(ctx context.Context, req *pb.GetDoctorListReq) (*pb.GetDoctorListResp, error) {
	doctors, total, err := model.GetDoctorList(config.DB, int(req.Page), int(req.PageSize), req.Department, req.Specialty)
	if err != nil {
		return nil, err
	}

	var doctorInfos []*pb.DoctorInfo
	for _, doctor := range doctors {
		doctorInfos = append(doctorInfos, &pb.DoctorInfo{
			DoctorId:    int64(doctor.ID),
			Name:        doctor.Name,
			Phone:       doctor.Phone,
			Specialty:   doctor.Specialty,
			Department:  doctor.Department,
			Title:       doctor.Title,
			Hospital:    doctor.Hospital,
			AvatarUrl:   doctor.AvatarUrl,
			AuditStatus: int32(doctor.AuditStatus),
		})
	}

	return &pb.GetDoctorListResp{
		Doctors: doctorInfos,
		Total:   total,
	}, nil
}

